home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / emacs.lha / emacs-19.16 / lib-src / aixcc.lex next >
Text File  |  1993-06-09  |  6KB  |  302 lines

  1. %Start ErrorText ErrorMessage OtherText
  2.  
  3. EC    [0-9][0-9][0-9][0-9]-[0-9][0-9][0-9]
  4. D    [0-9]
  5. D3    [0-9 ][0-9 ][0-9]
  6. D4    [0-9 ][0-9 ][0-9 ][0-9]
  7. D5    [0-9 ][0-9 ][0-9 ][0-9 ][0-9]
  8. DS    [0-9 ]
  9.  
  10. %{
  11. /* moore@wilma.cs.utk.edu
  12.  
  13.  * Hack to work around the AIX C compiler's brain-damaged error messages
  14.  * so that emacs can parse them.  It runs /bin/cc as a subprocess, and
  15.  * tries to rearrange the error messages so that (a) each message contains
  16.  * both the filename and line number where the error occurred, and (b)
  17.  * the error message(s) for a particular line get displayed *before* the
  18.  * line itself.
  19.  *
  20.  * to compile: 
  21.  * lex aixcc.lex
  22.  * cc -o aixcc lex.yy.c
  23.  *
  24.  *
  25.  * Copyright December 1991 by Keith Moore
  26.  *
  27.  * This program is free software; you can redistribute it and/or modify
  28.  * it under the terms of the GNU General Public License as published by
  29.  * the Free Software Foundation; either version 2 of the License, or
  30.  * (at your option) any later version.
  31.  * 
  32.  * This program is distributed in the hope that it will be useful,
  33.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  34.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  35.  * GNU General Public License for more details.
  36.  * 
  37.  * You should have received a copy of the GNU General Public License
  38.  * along with this program; if not, write to the Free Software
  39.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  40.  *
  41.  *
  42.  * TODO: figure out how the compiler counts file numbers for included
  43.  * files, keep track of which file corresponds to which number, and
  44.  * always output the right file name.
  45.  */
  46.  
  47. #include <stdio.h>
  48. #include <string.h>
  49.  
  50. char *current_file;
  51. int line;
  52. int debug = 0;
  53. char bigbuf[10240];
  54. char *bufptr = bigbuf;
  55. int last_line_was_error = 0;
  56.  
  57. spaces (s)
  58. char *s;
  59. {
  60.     while (*s++)
  61.     *bufptr++ = ' ';
  62. }
  63.  
  64. char *
  65. strsave (s)
  66. char *s;
  67. {
  68.     char *ptr = malloc (strlen (s) + 1);
  69.     strcpy (ptr, s);
  70.     return ptr;
  71. }
  72.  
  73. yywrap ()
  74. {
  75.     *bufptr = '\0';
  76.     bufptr = bigbuf;
  77.     while (*bufptr)
  78.     putc (*bufptr++, yyout);
  79.     return 1;
  80. }
  81.  
  82. %}
  83. %%
  84. ^File\ Line\ Column\ Message\ text[^\n]*    {
  85.    /*
  86.     * ignore this.  don't treat it as error text
  87.     */
  88. }
  89.  
  90. ^{DS}{DS}{DS}\ {D5}\ \|    {
  91.     /*
  92.      * (optional) nesting level, followed by line number, followed
  93.      * by the source code fragment that caused the error
  94.      */
  95.  
  96.     /*
  97.      * save the line number for later
  98.      */
  99.     line = atoi (yytext+4);
  100.  
  101.     if (debug) {
  102.     fprintf (yyout, "line <= %d\n", line);
  103.     fprintf (yyout, "%s\n", yytext);
  104.     }
  105.  
  106.     /*
  107.      * if the last line was an error message, to flush out all of
  108.      * the old source text before starting to save the new source text.
  109.      */
  110.     if (last_line_was_error) {
  111.     *bufptr = '\0';
  112.     bufptr = bigbuf;
  113.     while (*bufptr)
  114.         putc (*bufptr++, yyout);
  115.     bufptr = bigbuf;
  116.         last_line_was_error = 0;
  117.     }
  118.     /*
  119.      * stuff enough spaces in the text buffer so that the
  120.      * saved text will line up properly when displayed.
  121.      */
  122.     spaces (yytext);
  123.  
  124.     BEGIN ErrorText;    /* continue below */
  125. }
  126.  
  127. <ErrorText>[^\n]*$    {
  128.     char *ptr;
  129.  
  130.     /* 
  131.      * Save the text until we see the error message(s), then print it.
  132.      * This because emacs puts the error message at the top of the
  133.      * window, and it's nice to be able to see the text below it.
  134.      */
  135.  
  136.     ptr = yytext;
  137.     while (*ptr)
  138.     *bufptr++ = *ptr++;
  139.     *bufptr++ = '\n';
  140.  
  141.     BEGIN 0;
  142. }
  143.  
  144. ^Processing\ include\ file\ .*$    {
  145.     /*
  146.      * name of a new include file being processed.  Increment file number
  147.      * and remember the file name corresponding to this file number.
  148.      */
  149.  
  150.     current_file = strsave (yytext+24);
  151.     
  152.     if (debug) {
  153.     fprintf (yyout, "current_file <= %s\n", current_file);
  154.     fprintf (yyout, "%s\n", yytext);
  155.     }
  156. }
  157.  
  158. ^([a-z]\ -)?\ *{EC}:    {
  159.     /* 
  160.      * error message (which we print immediately) preceded by an
  161.      * error code (which we ignore)
  162.      */
  163.  
  164.     fprintf (yyout, "\"%s\", line %d: %c -", current_file, line, *yytext);
  165.     last_line_was_error = 1;
  166.     BEGIN ErrorMessage;
  167. }
  168.  
  169. ^{D3}\ {D5}\ {D4}\ {EC}:    {
  170.     /*
  171.      * (optional) nesting level, followed by line number, followed
  172.      * by column number, followed by error message text.
  173.      */
  174.  
  175.     /*
  176.      * save the line number for later
  177.      */
  178.     line = atoi (yytext+4);
  179.  
  180.     if (debug) {
  181.     fprintf (yyout, "line <= %d\n", line);
  182.     fprintf (yyout, "%s\n", yytext);
  183.     }
  184.  
  185.     /*
  186.      * if the last line was an error message, flush out all of
  187.      * the old source text before printing this error message.
  188.      */
  189.     if (last_line_was_error) {
  190.     *bufptr = '\0';
  191.     bufptr = bigbuf;
  192.     while (*bufptr)
  193.         putc (*bufptr++, yyout);
  194.     bufptr = bigbuf;
  195.         last_line_was_error = 0;
  196.     }
  197.     fprintf (yyout, "\"%s\", line %d:", current_file, line);
  198.     last_line_was_error = 1;
  199.     BEGIN ErrorMessage;
  200. }
  201.  
  202. <ErrorMessage>[^\n]*$    {
  203.     fprintf (yyout, "%s\n", yytext);
  204.     BEGIN 0;
  205. }
  206.  
  207.  
  208. ^[^ :]+".c:"\ *$    {
  209.     /* name of new source file being processed */
  210.  
  211.     char *ptr;
  212.  
  213.     if (current_file)
  214.     free (current_file);
  215.     ptr = strchr (yytext, ':');
  216.     *ptr = '\0';
  217.     current_file = strsave (yytext);
  218. }
  219.  
  220. ^[^\n]    {
  221.     /*
  222.      * other text starting with a newline.  We have to break it up this
  223.      * way to keep this rule from matching any of the above patterns
  224.      */
  225.  
  226.     if (last_line_was_error) {
  227.     *bufptr = '\0';
  228.     bufptr = bigbuf;
  229.     while (*bufptr)
  230.         putc (*bufptr++, yyout);
  231.     bufptr = bigbuf;
  232.         last_line_was_error = 0;
  233.     }
  234.  
  235.     *bufptr++ = *yytext;
  236.     BEGIN OtherText;
  237. }
  238.  
  239. <OtherText>[^\n]*$    {
  240.     char *ptr;
  241.  
  242.     ptr = yytext;
  243.     while (*ptr)
  244.     *bufptr++ = *ptr++;
  245.     *bufptr++ = '\n';
  246.  
  247.     BEGIN 0;
  248. }
  249.  
  250. \n    ;
  251.  
  252. %%
  253.  
  254. main (argc, argv)
  255. char **argv;
  256. {
  257.     int pfd[2];
  258.     int child_pid;
  259.     int i;
  260.  
  261.     current_file = strsave ("/dev/null");
  262.  
  263.     line = 0;
  264.  
  265.     for (i = 1; i < argc; ++i) {
  266.     char *ptr = strrchr (argv[i], '.');
  267.     if (ptr && ptr[1] == 'c' && ptr[2] == '\0') {
  268.         current_file = strsave (argv[i]);
  269.         break;
  270.     }
  271.     }
  272.  
  273.     if (pipe (pfd) < 0) {
  274.     perror ("pipe");
  275.     exit (1);
  276.     }
  277.     if ((child_pid = fork()) > 0) {
  278.     int status;
  279.  
  280.     close (pfd[1]);
  281.     yyin = fdopen (pfd[0], "r");
  282.     yyout = stderr;
  283.     yylex();
  284.  
  285.     wait (&status);
  286.     exit ((status >> 8) & 0xff);
  287.     }
  288.     else if (child_pid == 0) {
  289.     dup2 (pfd[1], 2);
  290.     close (pfd[0]);
  291.     close (pfd[1]);
  292.     argv[0] = "cc";
  293.     execv ("/bin/cc", argv);
  294.     perror ("/bin/cc");
  295.     exit (1);
  296.     }
  297.     else {
  298.     perror ("fork");
  299.     exit (1);
  300.     }
  301. }
  302.